home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / tracepoint.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  3.8 KB  |  138 lines

  1. #ifndef _LINUX_TRACEPOINT_H
  2. #define _LINUX_TRACEPOINT_H
  3.  
  4. /*
  5.  * Kernel Tracepoint API.
  6.  *
  7.  * See Documentation/tracepoint.txt.
  8.  *
  9.  * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
  10.  *
  11.  * Heavily inspired from the Linux Kernel Markers.
  12.  *
  13.  * This file is released under the GPLv2.
  14.  * See the file COPYING for more details.
  15.  */
  16.  
  17. #include <linux/types.h>
  18. #include <linux/rcupdate.h>
  19.  
  20. struct module;
  21. struct tracepoint;
  22.  
  23. struct tracepoint {
  24.     const char *name;        /* Tracepoint name */
  25.     int state;            /* State. */
  26.     void **funcs;
  27. } __attribute__((aligned(8)));
  28.  
  29.  
  30. #define TPPROTO(args...)    args
  31. #define TPARGS(args...)        args
  32.  
  33. #ifdef CONFIG_TRACEPOINTS
  34.  
  35. /*
  36.  * it_func[0] is never NULL because there is at least one element in the array
  37.  * when the array itself is non NULL.
  38.  */
  39. #define __DO_TRACE(tp, proto, args)                    \
  40.     do {                                \
  41.         void **it_func;                        \
  42.                                     \
  43.         rcu_read_lock_sched();                    \
  44.         it_func = rcu_dereference((tp)->funcs);            \
  45.         if (it_func) {                        \
  46.             do {                        \
  47.                 ((void(*)(proto))(*it_func))(args);    \
  48.             } while (*(++it_func));                \
  49.         }                            \
  50.         rcu_read_unlock_sched();                \
  51.     } while (0)
  52.  
  53. /*
  54.  * Make sure the alignment of the structure in the __tracepoints section will
  55.  * not add unwanted padding between the beginning of the section and the
  56.  * structure. Force alignment to the same alignment as the section start.
  57.  */
  58. #define DEFINE_TRACE(name, proto, args)                    \
  59.     static inline void trace_##name(proto)                \
  60.     {                                \
  61.         static const char __tpstrtab_##name[]            \
  62.         __attribute__((section("__tracepoints_strings")))    \
  63.         = #name ":" #proto;                    \
  64.         static struct tracepoint __tracepoint_##name        \
  65.         __attribute__((section("__tracepoints"), aligned(8))) =    \
  66.         { __tpstrtab_##name, 0, NULL };                \
  67.         if (unlikely(__tracepoint_##name.state))        \
  68.             __DO_TRACE(&__tracepoint_##name,        \
  69.                 TPPROTO(proto), TPARGS(args));        \
  70.     }                                \
  71.     static inline int register_trace_##name(void (*probe)(proto))    \
  72.     {                                \
  73.         return tracepoint_probe_register(#name ":" #proto,    \
  74.             (void *)probe);                    \
  75.     }                                \
  76.     static inline void unregister_trace_##name(void (*probe)(proto))\
  77.     {                                \
  78.         tracepoint_probe_unregister(#name ":" #proto,        \
  79.             (void *)probe);                    \
  80.     }
  81.  
  82. extern void tracepoint_update_probe_range(struct tracepoint *begin,
  83.     struct tracepoint *end);
  84.  
  85. #else /* !CONFIG_TRACEPOINTS */
  86. #define DEFINE_TRACE(name, proto, args)            \
  87.     static inline void _do_trace_##name(struct tracepoint *tp, proto) \
  88.     { }                                \
  89.     static inline void trace_##name(proto)                \
  90.     { }                                \
  91.     static inline int register_trace_##name(void (*probe)(proto))    \
  92.     {                                \
  93.         return -ENOSYS;                        \
  94.     }                                \
  95.     static inline void unregister_trace_##name(void (*probe)(proto))\
  96.     { }
  97.  
  98. static inline void tracepoint_update_probe_range(struct tracepoint *begin,
  99.     struct tracepoint *end)
  100. { }
  101. #endif /* CONFIG_TRACEPOINTS */
  102.  
  103. /*
  104.  * Connect a probe to a tracepoint.
  105.  * Internal API, should not be used directly.
  106.  */
  107. extern int tracepoint_probe_register(const char *name, void *probe);
  108.  
  109. /*
  110.  * Disconnect a probe from a tracepoint.
  111.  * Internal API, should not be used directly.
  112.  */
  113. extern int tracepoint_probe_unregister(const char *name, void *probe);
  114.  
  115. struct tracepoint_iter {
  116.     struct module *module;
  117.     struct tracepoint *tracepoint;
  118. };
  119.  
  120. extern void tracepoint_iter_start(struct tracepoint_iter *iter);
  121. extern void tracepoint_iter_next(struct tracepoint_iter *iter);
  122. extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
  123. extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
  124. extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
  125.     struct tracepoint *begin, struct tracepoint *end);
  126.  
  127. /*
  128.  * tracepoint_synchronize_unregister must be called between the last tracepoint
  129.  * probe unregistration and the end of module exit to make sure there is no
  130.  * caller executing a probe when it is freed.
  131.  */
  132. static inline void tracepoint_synchronize_unregister(void)
  133. {
  134.     synchronize_sched();
  135. }
  136.  
  137. #endif
  138.